use std::os::windows::io::RawHandle;
use std::{
    ffi::{CString, c_char},
    fs::File,
    io::{self, Read},
    os::windows::io::FromRawHandle,
    thread,
    time::Duration,
};
use windows_sys::Win32::Foundation::{DUPLICATE_SAME_ACCESS, HANDLE, INVALID_HANDLE_VALUE}; //, DuplicateHandle
use windows_sys::Win32::Security::SECURITY_ATTRIBUTES;
use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, STD_OUTPUT_HANDLE, SetStdHandle};
// use windows_sys::Win32::System::Threading::GetCurrentProcess;
use libc::{dup2, open_osfhandle};
use windows_sys::core::BOOL;

const STDOUT_FILENO: i32 = 1;
const STDERR_FILENO: i32 = 2;





#[link(name = "kernel32")]
unsafe extern "system" {
    pub fn CreatePipe(
        hReadPipe: *mut HANDLE,
        hWritePipe: *mut HANDLE,
        lpPipeAttributes: *mut SECURITY_ATTRIBUTES,
        nSize: u32,
    ) -> BOOL;

    fn DuplicateHandle(
        hSourceProcessHandle: HANDLE,
        hSourceHandle: HANDLE,
        hTargetProcessHandle: HANDLE,
        lpTargetHandle: *mut HANDLE,
        dwDesiredAccess: u32,
        bInheritHandle: i32,
        dwOptions: u32,
    ) -> i32;

    fn GetCurrentProcess() -> HANDLE;
}

unsafe extern "C" {
    fn ffmpeg_main(cmdline_str: *const c_char, argc: i32, argv: *const *const c_char) -> i32;
    fn ffmpeg_stop();
    //fn set_log_pipe_fd(fd: i32);
}

fn redirect_c_stdout_and_stderr_to_pipe(write_pipe: HANDLE) {
    unsafe {
        // // 1. 重定向 libc 的 stderr（ffmpeg 依赖）
        let fd = open_osfhandle(write_pipe as isize, 0);
        if fd < 0 {
            panic!("open_osfhandle 失败");
        }

        // if dup2(fd, STDOUT_FILENO) != 0 {
        //     panic!("dup2 重定向 stdout 失败");
        // }

        if dup2(fd, STDERR_FILENO) != 0 {
            panic!("dup2 重定向 stderr 失败");
        }

        // 2. 重定向 Windows API 的 stderr
        if SetStdHandle(STD_ERROR_HANDLE, write_pipe) == 0 {
            panic!("SetStdHandle(STD_ERROR_HANDLE) 失败");
        }
    }
}

fn main() {
    unsafe {
        println!("🚀 启动 Rust + FFmpeg");

        let (read_pipe, write_pipe) = create_pipe_and_redirect_stdout().expect("创建管道失败");

        // unsafe{
        // // 传递 write_pipe 的句柄给 C 的日志回调
        //     // Windows HANDLE 转为 CRT fd
        //     let fd = libc::open_osfhandle(write_pipe as isize, 0);
        //     if fd < 0 {
        //         panic!("open_osfhandle failed");
        //     }
        //     set_log_pipe_fd(fd);
        // }

        // ✅ 替换 libc 的 stdout 为 write_pipe，确保 ffmpeg 输出能被捕获
        redirect_c_stdout_and_stderr_to_pipe(write_pipe);

        // duplicate handle in main thread
        // let mut dup_read: HANDLE = INVALID_HANDLE_VALUE;
        // let success = unsafe {
        //     DuplicateHandle(
        //         GetCurrentProcess(),
        //         read_pipe,
        //         GetCurrentProcess(),
        //         &mut dup_read,
        //         0,
        //         0,
        //         DUPLICATE_SAME_ACCESS,
        //     )
        // };
        // if success == 0 {
        //     panic!("❌ DuplicateHandle 失败");
        // }

        // // ✅ cast to isize, move safely into thread
        // let dup_read = dup_read as isize;

        let mut file = File::from_raw_handle(read_pipe as RawHandle);
        let reader_thread = thread::spawn(move || {
            println!("👀 读取线程启动");
            let mut buffer = [0u8; 1024];

            loop {
                println!("🌀 尝试读取...");
                match file.read(&mut buffer) {
                    Ok(0) => {
                        println!("📴 EOF 到达，退出读取线程");
                        break;
                    }
                    Ok(n) => {
                        println!("📥 读取到 {} 字节", n);
                        print!("{}", String::from_utf8_lossy(&buffer[..n]));
                    }
                    Err(e) => {
                        eprintln!("❌ 读取失败: {:?}", e);
                        break;
                    }
                }
            }
        });

        // 启动 FFmpeg 主线程
        let ffmpeg_thread = thread::spawn(|| {
            test_record10();
            println!("✅  test_record10(); 完成");
        });

        ffmpeg_thread.join().unwrap();
        println!("✅  test_record10() JOIN 完成");

        // ✅ 关闭写端，通知读取线程 EOF

        windows_sys::Win32::Foundation::CloseHandle(write_pipe);

        reader_thread.join().unwrap();
        println!("✅ FFmpeg 完成,reader_thread");
    }
}

fn test_record10() {
    let args = vec![
        "ffmpeg",
        "-loglevel",
        "info",
        "-y",
        "-f",
        "gdigrab",
        "-i",
        "desktop",
        "-r",
        "10",
        "-t",
        "10",
        "-fs",
        "100M",
        "-b:v",
        "1M",
        "test.mp4",
    ];

    let cstrings: Vec<CString> = args.iter().map(|s| CString::new(*s).unwrap()).collect();
    let argv: Vec<*const c_char> = cstrings.iter().map(|cs| cs.as_ptr()).collect();
    let cmdline_str = CString::new(args.join(" ")).unwrap();

    // 停止 FFmpeg
    let stopper = thread::spawn(|| {
        thread::sleep(Duration::from_secs(10));
        println!("🛑 10 秒到了，调用 ffmpeg_stop()");
        unsafe {
            ffmpeg_stop();
        }
    });

    unsafe {
        ffmpeg_main(cmdline_str.as_ptr(), argv.len() as i32, argv.as_ptr());
    }

    stopper.join().unwrap();
}

fn create_pipe_and_redirect_stdout() -> io::Result<(HANDLE, HANDLE)> {
    unsafe {
        let mut read_pipe: HANDLE = std::ptr::null_mut();
        let mut write_pipe: HANDLE = std::ptr::null_mut();

        let mut sa = SECURITY_ATTRIBUTES {
            nLength: std::mem::size_of::<SECURITY_ATTRIBUTES>() as u32,
            lpSecurityDescriptor: std::ptr::null_mut(),
            bInheritHandle: 1, // TRUE
        };

        let result = CreatePipe(&mut read_pipe, &mut write_pipe, &mut sa, 0);
        if result == 0 {
            return Err(io::Error::last_os_error());
        }

        // 设置 stderr 为 write_pipe
        //if SetStdHandle(STD_ERROR_HANDLE, write_pipe) == 0 {
        //if SetStdHandle(STD_OUTPUT_HANDLE, write_pipe) == 0 {
        //    return Err(io::Error::last_os_error());
        //}

        Ok((read_pipe, write_pipe))
    }
}
